home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 106 / EnigmaAmiga106CD.iso / software / utilities / installer / gui api / example / libstuff.c < prev   
Encoding:
C/C++ Source or Header  |  1999-08-28  |  18.1 KB  |  584 lines

  1.  
  2. #include "installergui_base.h"
  3. #include "includes.h"
  4. #include "installergui_data.h"
  5.  
  6. #include <string.h>
  7.  
  8. /********************************************************************
  9.  *
  10.  *  DESCRIPTION
  11.  *
  12.  *  - private for initialisation and cleanup code for the
  13.  *    library; you may also declare library-global data here
  14.  *    (note that libcode must be re-entrant!)
  15.  *  - several support functions
  16.  *
  17.  */
  18.  
  19. /********************************************************************
  20.  *
  21.  *  STATIC
  22.  *
  23.  */
  24.  
  25. /********************************************************************
  26.  *
  27.  *  EXTERN
  28.  *
  29.  */
  30.  
  31. /********************************************************************
  32.  *
  33.  *  PUBLIC
  34.  *
  35.  */
  36.  
  37. struct Library *MUIMasterBase = NULL;
  38.  
  39. /********************************************************************
  40.  *
  41.  *  CODE
  42.  *
  43.  */
  44.  
  45. /********************************************************************/
  46.  
  47. // this helps to center the a text within a floattext object!
  48. // (suggested by Jens Langner)
  49. char *guistuff_CenterText(char *text)
  50. {
  51.   char *centtext;
  52.   int i, numlf;
  53.  
  54.   for (i=0, numlf=0; text[i]; i++, numlf += (text[i]=='\n')?1:0);
  55.  
  56.   centtext = sav_AllocVec(strlen(text) + (numlf*4) + 1, MEMF_ANY|MEMF_CLEAR);
  57.   if (!centtext) { return(text); }
  58.  
  59.   for(i=0; strlen(text) > 0; text += i)
  60.   {
  61.     char *poschr = strstr(text, "\n");
  62.  
  63.     i = 1 + strlen(text) - (poschr ? strlen(poschr) : 1);
  64.     strcat(centtext, "\33c");
  65.     strncat(centtext, text, i);
  66.   }
  67.  
  68.   return(centtext);
  69. }
  70.  
  71. /********************************************************************/
  72.  
  73. // create a radio-button
  74. APTR guistuff_InitRadio(BOOL selected, BOOL disabled)
  75. {
  76.   #ifdef DEBUG
  77.   DEBUG_MAKRO
  78.   #endif
  79.  
  80.   return(ImageObject,
  81.            MUIA_Image_Spec, 16,
  82.            MUIA_InputMode, MUIV_InputMode_Immediate,
  83.            MUIA_Selected, selected,
  84.            MUIA_Disabled, disabled,
  85.          End);
  86. }
  87.  
  88. /********************************************************************/
  89.  
  90. // handle a gui event: return TRUE if the gui has to wait, FALSE otherwise
  91. BOOL guistuff_HandleGUIEvent(APTR application, long event)
  92. {
  93.   #ifdef DEBUG
  94.   DEBUG_MAKRO
  95.   #endif
  96.  
  97.   {
  98.     // set app->app_Quit to TRUE when quit, otherwise do "nothing"
  99.     struct Application *app = application;
  100.  
  101.     switch (event)
  102.     {
  103.       // der proceed button
  104.       case GUIEVENT_BACK:
  105.       case GUIEVENT_PROCEED: { return (FALSE); }
  106.  
  107.       // abort button
  108.       // (special handling in special cases: SWING mode: if set, then
  109.       // the "cancel" button is quiet!)
  110.       case GUIEVENT_ABORT:
  111.       {
  112.         if (app->app_SWING_Mode) { return (FALSE); }
  113.       }
  114.  
  115.       // user wants to quit
  116.       case GUIEVENT_QUIT:
  117.       {
  118.         // do not prompt the user within TRAP handling
  119.         if (app->app_TRAP_Mode) { return (FALSE); }
  120.  
  121.         //
  122.         else if (igui_Request(app, NULL, app->app_Texts[YES_NO], app->app_Texts[REALLY_QUIT], NULL))
  123.         {
  124.           // if we are in SWING mode, we have to reset the SWING mode first
  125.           igui_SWING_Mode(app, FALSE);
  126.  
  127.           app->app_Quit = TRUE;
  128.           return (FALSE);
  129.         }
  130.       }
  131.     }
  132.  
  133.     // ansonsten weiter warten!
  134.     return (TRUE);
  135.   }
  136. }
  137.  
  138. /********************************************************************/
  139.  
  140. // change tho panels of the installer gui
  141. BOOL guistuff_NewContent(APTR application, APTR newobject)
  142. {
  143.   #ifdef DEBUG
  144.   DEBUG_MAKRO
  145.   #endif
  146.  
  147.   {
  148.     struct Application *app = (struct Application *) application;
  149.  
  150.     if (!newobject)
  151.     {
  152.       app->app_Error = GUIERROR_NO_GUI_OBJECT;
  153.       return(FALSE);
  154.     }
  155.  
  156.     if(DoMethod(app->app_MainRoot, MUIM_Group_InitChange))
  157.     {
  158.       // remove old object. Add new one.
  159.       DoMethod(app->app_MainRoot, OM_REMMEMBER, app->app_CurrentObject);
  160.       DoMethod(app->app_MainRoot, OM_ADDMEMBER, newobject);
  161.  
  162.       // dispose old object
  163.       DisposeObject(app->app_CurrentObject);
  164.  
  165.       // new object gets the current one
  166.       app->app_CurrentObject = newobject;
  167.  
  168.       // let the group relayout itself.
  169.       DoMethod(app->app_MainRoot, MUIM_Group_ExitChange);
  170.     }
  171.     return(TRUE);
  172.   }
  173. }
  174.  
  175. /********************************************************************/
  176.  
  177. APTR guistuff_InitSimpleText(char *text)
  178. {
  179.   #ifdef DEBUG
  180.   DEBUG_MAKRO
  181.   #endif
  182.  
  183.   return(ListviewObject,
  184.            MUIA_Listview_Input, FALSE,
  185.            //MUIA_List_Format, "P=\33c",
  186.            MUIA_Listview_List, FloattextObject,
  187.              MUIA_Frame, MUIV_Frame_None,
  188.              MUIA_Floattext_Text, guistuff_CenterText(text),
  189.              MUIA_Background, MUII_TextBack,
  190.              //MUIA_Font, MUIV_Font_Fixed,
  191.            End,
  192.          End);
  193. }
  194.  
  195. /********************************************************************/
  196.  
  197. // mx implementation for two mx buttons
  198. void __asm __saveds guistuff_MXTwoFun(register __a1 APTR *data)
  199. {
  200.   set((APTR) data[0], MUIA_Selected, TRUE);
  201.   set((APTR) data[0], MUIA_Pressed, FALSE);
  202.   set((APTR) data[1], MUIA_Selected, FALSE);
  203. }
  204.  
  205. /********************************************************************/
  206.  
  207. // mx implementation for three mx buttons
  208. void __asm __saveds guistuff_MXThreeFun(register __a1 APTR *data)
  209. {
  210.   set((APTR) data[0], MUIA_Selected, TRUE);
  211.   set((APTR) data[0], MUIA_Pressed, FALSE);
  212.   set((APTR) data[1], MUIA_Selected, FALSE);
  213.   set((APTR) data[2], MUIA_Selected, FALSE);
  214. }
  215.  
  216. /********************************************************************/
  217.  
  218. // peek anything to anywhere :)
  219. void __asm guistuff_SetValFun(register __a1 APTR *data)
  220. {
  221.   *((APTR *) data[0]) = (APTR) data[1];
  222. }
  223.  
  224. /********************************************************************/
  225.  
  226. // just refresh the gui
  227. void guistuff_Refresh(APTR application)
  228. {
  229.   #ifdef DEBUG
  230.   DEBUG_MAKRO
  231.   #endif
  232.  
  233.   DoMethod(((struct Application *) application)->app_Application, MUIM_Application_InputBuffered);
  234. }
  235.  
  236. /********************************************************************/
  237.  
  238. // build a new path
  239. char *guistuff_BuildPath(char *path, char *file)
  240. {
  241.   long newpathlen = strlen(path) + strlen(file) + 5;
  242.   char *newpath;
  243.  
  244.   if (newpath = sav_AllocVec(newpathlen, MEMF_ANY))
  245.   {
  246.     strcpy(newpath, path);
  247.     if (DOSFALSE == AddPart(newpath, file, newpathlen)) { sav_FreeVec(newpath); newpath = NULL; }
  248.   }
  249.  
  250.   return(newpath);
  251. }
  252.  
  253. /********************************************************************/
  254.  
  255. static void __asm __saveds gui_BTMKDirOpenFun(register __a2 APTR, register __a1 APTR *);
  256. static void __asm __saveds gui_BTMKDirDrivesFun(register __a2 APTR, register __a1 APTR *);
  257. static void __asm __saveds gui_BTParentFun(register __a2 APTR, register __a1 APTR *);
  258. static void __asm __saveds gui_LVDirlistSelectFun(register __a2 APTR, register __a1 APTR *);
  259. static void __asm __saveds gui_LVDriveslistSelectFun(register __a2 APTR, register __a1 APTR *);
  260. static void __asm __saveds gui_STNewDirFun(register __a2 APTR, register __a1 APTR *);
  261.  
  262. static const struct Hook gui_bt_parent_hook = { { NULL, NULL }, (VOID *) gui_BTParentFun, NULL, NULL };
  263. static const struct Hook gui_lv_dirlistselect_hook = { { NULL, NULL }, (VOID *) gui_LVDirlistSelectFun, NULL, NULL };
  264. static const struct Hook gui_lv_driveslistselect_hook = { { NULL, NULL }, (VOID *) gui_LVDriveslistSelectFun, NULL, NULL };
  265. static const struct Hook gui_bt_mkdiropen_hook = { { NULL, NULL }, (VOID *) gui_BTMKDirOpenFun, NULL, NULL };
  266. static const struct Hook gui_bt_mkdirdrives_hook = { { NULL, NULL }, (VOID *) gui_BTMKDirDrivesFun, NULL, NULL };
  267. static const struct Hook gui_st_newdir_hook = { { NULL, NULL }, (VOID *) gui_STNewDirFun, NULL, NULL };
  268.  
  269. // since ASKFILE and ASKDIR do nearly the same, we can put them together into
  270. // only one function
  271. char *guistuff_AskFile_AskDir(APTR application, struct FunctionEnvironment *localenv, BOOL askdir)
  272. {
  273.   #ifdef DEBUG
  274.   DEBUG_MAKRO
  275.   #endif
  276.  
  277.   {
  278.     struct Application *app = (struct Application *) application;
  279.  
  280.     char *path, *newpath,
  281.          *file;
  282.  
  283.     char file_cpy[128], dir_cpy[256];
  284.  
  285.     // error or default: return the empty string ""
  286.     char *retval = app->app_Texts[EMPTY];
  287.  
  288.     APTR ASKDIR_ST_Path, ASKDIR_ST_File, ASKDIR_LV_Dirlist;
  289.  
  290.     APTR BT_parent, BT_drives, BT_mkdir,
  291.          LV_DrivesLV, LV_DirLV, LV_Driveslist,
  292.          GR_buttons,
  293.          obj;
  294.  
  295.     // extract path and file for better handling with mui
  296.     strncpy((char *) &dir_cpy, (char *) localenv->fe_Default, 255);
  297.     if (askdir) { file_cpy[0] = 0; }
  298.     else
  299.     {
  300.       sav_PutChar(PathPart((STRPTR) &dir_cpy), 0L);
  301.       strncpy((char *) &file_cpy, (char *) FilePart((char *) localenv->fe_Default), 128);
  302.     }
  303.  
  304.     // create the gui object
  305.     obj = GroupObject,
  306.             Child, TextObject,
  307.               MUIA_Frame, MUIV_Frame_None,
  308.               MUIA_Text_Contents, localenv->fe_Prompt,
  309.               MUIA_Text_SetMin, TRUE,
  310.               MUIA_Text_PreParse, "\33c",
  311.             End,
  312.             Child, LV_DirLV = ListviewObject,
  313.               MUIA_Listview_List, app->app_MkdirRelatedDirlist = ASKDIR_LV_Dirlist = DirlistObject,
  314.                 MUIA_Dirlist_DrawersOnly, askdir,
  315.                 MUIA_Dirlist_Directory, &dir_cpy,
  316.               End,
  317.               MUIA_Background, MUII_ListBack,
  318.               MUIA_Frame, MUIV_Frame_InputList,
  319.               MUIA_ShowMe, !localenv->fe_Disk,
  320.             End,
  321.             Child, LV_DrivesLV = ListviewObject,
  322.               MUIA_Background, MUII_ListBack,
  323.               MUIA_Frame, MUIV_Frame_InputList,
  324.               MUIA_Listview_List, LV_Driveslist = VolumelistObject,
  325.                 //
  326.               End,
  327.               MUIA_ShowMe, localenv->fe_Disk,
  328.             End,
  329.             Child, ASKDIR_ST_Path = StringObject,
  330.               MUIA_Frame, MUIV_Frame_String,
  331.               MUIA_String_Format, MUIV_String_Format_Center,
  332.               MUIA_String_Contents, &dir_cpy,
  333.               MUIA_String_MaxLen, 128,
  334.               MUIA_ShowMe, !localenv->fe_Disk,
  335.             End,
  336.             Child, ASKDIR_ST_File = StringObject,
  337.               MUIA_Frame, MUIV_Frame_String,
  338.               MUIA_String_Format, MUIV_String_Format_Center,
  339.               MUIA_String_Contents, &file_cpy,
  340.               MUIA_String_MaxLen, 128,
  341.               MUIA_ShowMe, !askdir,
  342.             End,
  343.             Child, GR_buttons = GroupObject,
  344.               MUIA_Group_Horiz, TRUE,
  345.               Child, BT_parent = SimpleButton(app->app_Texts[BUTTON_PARENT]),
  346.               Child, BT_drives = SimpleButton(app->app_Texts[BUTTON_DRIVES]),
  347.               Child, BT_mkdir = SimpleButton(app->app_Texts[BUTTON_MKDIR]),
  348.             End,
  349.           End;
  350.  
  351.     if (obj)
  352.     {
  353.       // join the string gadget and the listview, so they notify each other
  354.       DoMethod(ASKDIR_ST_Path, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
  355.                ASKDIR_LV_Dirlist, 3, MUIM_Set, MUIA_Dirlist_Directory, MUIV_TriggerValue);
  356.       DoMethod(ASKDIR_LV_Dirlist, MUIM_Notify, MUIA_Dirlist_Directory, MUIV_EveryTime,
  357.                ASKDIR_ST_Path, 3, MUIM_Set, MUIA_String_Contents, MUIV_TriggerValue);
  358.  
  359.       // the active lv-entry changed
  360.       DoMethod(ASKDIR_LV_Dirlist, MUIM_Notify, MUIA_List_Active, MUIV_EveryTime,
  361.                MUIV_Notify_Self, 5, MUIM_CallHook, &gui_lv_dirlistselect_hook,
  362.                ASKDIR_ST_Path, ASKDIR_ST_File, ASKDIR_LV_Dirlist);
  363.  
  364.       // the user entered a new directory, so we have to update the listview
  365.       DoMethod(ASKDIR_ST_Path, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
  366.                MUIV_Notify_Self, 5, MUIM_CallHook, &gui_st_newdir_hook, ASKDIR_ST_Path, ASKDIR_ST_File, ASKDIR_LV_Dirlist);
  367.  
  368.       // the user selected a new volume from the volumes list
  369.       DoMethod(LV_Driveslist, MUIM_Notify, MUIA_List_Active, MUIV_EveryTime,
  370.                MUIV_Notify_Self, 10, MUIM_CallHook, &gui_lv_driveslistselect_hook,
  371.                obj, LV_DrivesLV, LV_DirLV, ASKDIR_ST_Path, ASKDIR_ST_File, GR_buttons, ASKDIR_LV_Dirlist, askdir);
  372.  
  373.       // we have to create a new directory; note, that we created the "makedir" stuff at the beginning
  374.       DoMethod(BT_mkdir, MUIM_Notify, MUIA_Pressed, FALSE,
  375.                MUIV_Notify_Self, 4, MUIM_CallHook, &gui_bt_mkdiropen_hook, ASKDIR_ST_Path, app);
  376.  
  377.       //
  378.       DoMethod(BT_drives, MUIM_Notify, MUIA_Pressed, FALSE,
  379.                MUIV_Notify_Self, 8, MUIM_CallHook, &gui_bt_mkdirdrives_hook, obj, LV_DrivesLV, LV_DirLV, ASKDIR_ST_Path, ASKDIR_ST_File, GR_buttons);
  380.  
  381.       // move to parent dir, if one presses "Parent"
  382.       DoMethod(BT_parent, MUIM_Notify, MUIA_Pressed, FALSE,
  383.                MUIV_Notify_Self, 5, MUIM_CallHook, &gui_bt_parent_hook, ASKDIR_ST_Path, ASKDIR_ST_File, ASKDIR_LV_Dirlist);
  384.  
  385.       //
  386.       if (guistuff_NewContent(app, obj))
  387.       {
  388.         //
  389.         igui_WaitApp(app);
  390.         if (!igui_QuitApp(app))
  391.         {
  392.           // an now get a copy of the selected file-name or just the path-name
  393.           GetAttr(MUIA_String_Contents, ASKDIR_ST_Path, (ULONG *) &path);
  394.           GetAttr(MUIA_String_Contents, ASKDIR_ST_File, (ULONG *) &file);
  395.  
  396.           //
  397.           if (askdir)
  398.           {
  399.             newpath = sav_DupString2(path);
  400.             if (newpath) { retval = newpath; }
  401.             else         { /* OUT OF MEMORY */ }
  402.           }
  403.  
  404.           //
  405.           else
  406.           {
  407.             retval = guistuff_BuildPath(path, file);
  408.             if (!retval) { /* OUT OF MEMORY */ retval = app->app_Texts[EMPTY]; }
  409.           }
  410.         }
  411.         else { /* user wants to quit */ }
  412.       }
  413.       else { /* NO GUI OBJECT */ }
  414.     }
  415.     else { /* NO GUI OBJECT */ }
  416.  
  417.     //
  418.     igui_EmptyPanel(app);
  419.     return(retval);
  420.   }
  421. }
  422.  
  423. static void __asm __saveds gui_BTParentFun(register __a2 APTR obj, register __a1 APTR *data)
  424. {
  425.   // move to the parent directory
  426.  
  427.   // data[0] - string gadget "Directory"
  428.   // data[1] - string gadget "File"
  429.   // data[2] - Dirlist object
  430.  
  431.   BPTR lock, parent;
  432.  
  433.   char *str,
  434.        path[128];
  435.  
  436.   GetAttr(MUIA_String_Contents, (APTR) data[0], (ULONG *) &str);
  437.   if (lock = Lock(str, SHARED_LOCK))
  438.   {
  439.     if (parent = ParentDir(lock))
  440.     {
  441.       if (DOSFALSE != NameFromLock(parent, (char *) &path, 127))
  442.       {
  443.         SetAttrs(data[1], MUIA_String_Contents, NULL, TAG_DONE);
  444.         SetAttrs(data[2], MUIA_Dirlist_Directory, &path, TAG_DONE);
  445.       }
  446.       else { /* path[128] may be too short */ DisplayBeep(NULL); }
  447.  
  448.       UnLock(parent);
  449.     }
  450.     else { /* unable to move to parent */ DisplayBeep(NULL); }
  451.  
  452.     UnLock(lock);
  453.   }
  454.   else { /* no lock */ DisplayBeep(NULL); }
  455. }
  456.  
  457. static void __asm __saveds gui_LVDirlistSelectFun(register __a2 APTR obj, register __a1 APTR *data)
  458. {
  459.   // the active item of the dirlist changed; if the new ective one is
  460.   // a file, then copy the name to the string gadget, otherweise
  461.   // selected item is a dir) change to the new directory
  462.  
  463.   // data[0] - string gadget "Directory"
  464.   // data[1] - string gadget "File"
  465.   // data[2] - Dirlist object
  466.  
  467.   long active, path;
  468.   struct FileInfoBlock *fib;
  469.   char str_copy[256];
  470.  
  471.   GetAttr(MUIA_List_Active, obj, (ULONG *) &active);
  472.   if (active >= 0)
  473.   {
  474.     DoMethod(obj, MUIM_List_GetEntry, active, &fib);
  475.  
  476.     // selected item is a directory
  477.     if (fib->fib_DirEntryType > 0)
  478.     {
  479.       GetAttr(MUIA_String_Contents, data[0], (ULONG *) &path);
  480.  
  481.       strncpy((char *) &str_copy, (char *) path, 255);
  482.       AddPart((STRPTR) &str_copy, (STRPTR) &(fib->fib_FileName), 255);
  483.  
  484.       SetAttrs(data[1], MUIA_String_Contents, NULL, TAG_DONE);
  485.       SetAttrs(data[2], MUIA_Dirlist_Directory, &str_copy, TAG_DONE);
  486.     }
  487.  
  488.     // the selected item is a file
  489.     else if (fib->fib_DirEntryType < 0)
  490.     {
  491.       SetAttrs(data[1], MUIA_String_Contents, &(fib->fib_FileName), TAG_DONE);
  492.     }
  493.   }
  494. }
  495.  
  496. static void __asm __saveds gui_LVDriveslistSelectFun(register __a2 APTR obj, register __a1 APTR *data)
  497. {
  498.   // the user selected an entry from the drives list -> move to the
  499.   // new directory
  500.  
  501.   // data[0] - ASKFILE/ASKDIR's root object
  502.   // data[1] - listview for the Volumelist
  503.   // data[2] - listview for the Dirlist
  504.   // data[3] - string gadget "Directory"
  505.   // data[4] - string gadget "File"
  506.   // data[5] - the 3 buttons
  507.   // data[6] - Dirlist object itself
  508.   // data[7] - the flag, if this is called by ASKDIR or ASKFILE
  509.  
  510.   long active;
  511.   char *path;
  512.  
  513.   GetAttr(MUIA_List_Active, obj, (ULONG *) &active);
  514.   if (active >= 0)
  515.   {
  516.     DoMethod(obj, MUIM_List_GetEntry, active, &path);
  517.     if (DoMethod((APTR) data[0], MUIM_Group_InitChange))
  518.     {
  519.       set((APTR) data[5], MUIA_ShowMe, TRUE);
  520.       set((APTR) data[4], MUIA_ShowMe, !data[7]);
  521.       set((APTR) data[3], MUIA_ShowMe, TRUE);
  522.       set((APTR) data[2], MUIA_ShowMe, TRUE);
  523.       set((APTR) data[1], MUIA_ShowMe, FALSE);
  524.       DoMethod((APTR) data[0], MUIM_Group_ExitChange);
  525.     }
  526.     SetAttrs(data[4], MUIA_String_Contents, NULL, TAG_DONE);
  527.     SetAttrs(data[6], MUIA_Dirlist_Directory, path, TAG_DONE);
  528.   }
  529. }
  530.  
  531. static void __asm __saveds gui_BTMKDirOpenFun(register __a2 APTR obj, register __a1 APTR *data)
  532. {
  533.   // open the "MakeDir" window
  534.  
  535.   // data[0] - string gadget "Directory"
  536.   // data[1] - pointer to the Application structure
  537.  
  538.   struct Application *app = (struct Application *) data[1];
  539.   long path;
  540.  
  541.   GetAttr(MUIA_String_Contents, (APTR) data[0], (ULONG *) &path);
  542.  
  543.   set(app->app_MkdirName, MUIA_String_Contents, path);
  544.   set(app->app_MkdirWindow, MUIA_Window_Open, TRUE);
  545.   set(app->app_MainWindow, MUIA_Window_Sleep, TRUE);
  546. }
  547.  
  548. static void __asm __saveds gui_BTMKDirDrivesFun(register __a2 APTR obj, register __a1 APTR *data)
  549. {
  550.   // change the gui to the Volumelist, thus, we have to show some
  551.   // objects and "un-show" some others!
  552.  
  553.   if (DoMethod((APTR) data[0], MUIM_Group_InitChange))
  554.   {
  555.     set((APTR) data[5], MUIA_ShowMe, FALSE);
  556.     set((APTR) data[4], MUIA_ShowMe, FALSE);
  557.     set((APTR) data[3], MUIA_ShowMe, FALSE);
  558.     set((APTR) data[2], MUIA_ShowMe, FALSE);
  559.     set((APTR) data[1], MUIA_ShowMe, TRUE);
  560.     DoMethod((APTR) data[0], MUIM_Group_ExitChange);
  561.   }
  562. }
  563.  
  564. static void __asm __saveds gui_STNewDirFun(register __a2 APTR obj, register __a1 APTR *data)
  565. {
  566.   // the user entered a new path into the string gadget ->
  567.   // check if this path is valid (if not, use "SYS:") and set
  568.   // the new path to the listview
  569.  
  570.   // data[0] - string gadget "Directory"
  571.   // data[1] - string gadget "File"
  572.   // data[2] - dirlist gadget
  573.  
  574.   char *newpath;
  575.   GetAttr(MUIA_String_Contents, (APTR) data[0], (ULONG *) &newpath);
  576.  
  577.   // if the entered path does not exist, use SYS: instead
  578.   if (!sav_DirExists(newpath)) { newpath = "SYS:"; SetAttrs((APTR) data[0], MUIA_String_Contents, newpath, TAG_DONE); }
  579.  
  580.   SetAttrs((APTR) data[1], MUIA_String_Contents, NULL, TAG_DONE);
  581.   SetAttrs((APTR) data[2], MUIA_Dirlist_Directory, newpath, TAG_DONE);
  582. }
  583.  
  584.